Skip to content

Show a more useful error when a Nikon High Efficiency NEF fails to load - #812

Merged
marcinz606 merged 3 commits into
marcinz606:mainfrom
seanharding:fix/nikon-high-efficiency-nef
Aug 12, 2026
Merged

Show a more useful error when a Nikon High Efficiency NEF fails to load#812
marcinz606 merged 3 commits into
marcinz606:mainfrom
seanharding:fix/nikon-high-efficiency-nef

Conversation

@seanharding

@seanharding seanharding commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

We can't load Nikon High Efficiency NEF files because libraw doesn't support the codec. This creates a more useful error message if someone tries to open one (and also fixes wrapping in the toast, so the whole message is visible).

Related to #808

seanharding and others added 3 commits August 11, 2026 19:02
Reported as "NegPy won't open this NEF" on a Z 8 file. It is not a NEF
fault: the camera recorded it in High Efficiency (HE / HE*), which is
intoPIX TicoRAW under a licensed codec.

Nothing in the tags gives it away. The TIFF Compression reads 34713,
"Nikon NEF Compressed" -- the same value a lossless NEF carries -- so
libraw parses the file, reports the full 8280x5520 sensor and a valid
crop, and only fails when the payload is unpacked, with "Unsupported file
format or not RAW file". To someone whose other NEFs all work, that reads
as a corrupt file. Only the payload distinguishes them: the strip opens
with a plain-text intoPIX vendor marker, and the ratio is 0.357 against
~0.55-0.70 for lossless.

`unsupported_raw_reason` recognises that marker and returns wording that
says what to do -- re-shoot Lossless Compressed, or convert to DNG. The
loader stays lazy: the check runs only once a decode has already failed,
so a file that works never pays for it (measured 1.5 ms on a lossless
NEF, which is 1.5 ms saved on every decode of every good file). Anything
it does not recognise keeps libraw's own message, which is the honest
answer for a genuinely corrupt or unknown file.

Ruled out on the way: stripped MakerNotes (intact, 67 KB across 77 Nikon
tags) and a truncated file (every other IFD reads, including a
full-resolution JPEG preview).

Verified through the app headless -- the status line, the error signal
and load_failed all carry the new wording -- and the detector is tested
against a byte-built synthetic HE NEF as well as the real one, so it does
not depend on a single sample.
The toast was an unwrapped QLabel. Fine for "merging exposures"; not for
a message that has to say what went wrong and what to do about it, which
ran off both edges.

It now wraps within a share of the canvas width. Two bounds, because one
is not enough: the maximum keeps it clear of the edges, and the minimum
stops Qt's wrapping sizeHint -- which aims for a squarish block -- folding
a sentence into five narrow lines when it has the width for two. Short
toasts keep their natural size. The bounds are applied when the message
is posted as well as on resize, since a load failure can post one before
the HUD has ever been resized.

Measured at 1400px canvas: the unsupported-raw message goes from one
overflowing line to 770x52, and "merging exposures" is unchanged at
327x34.

The NEF message is shortened to suit, saying the same thing in half the
words.

Noted while rendering it, not changed: showMessage lowercases every
toast, so this one reads "nikon high efficiency (he) raw -- negpy cannot
decode this format ... convert to dng". That is a good voice for activity
toasts and it flattens the acronyms in anything the user has to act on.
Left alone because it is a house-style decision rather than a fault, and
it predates this change; worth a look if error toasts become common.
@marcinz606
marcinz606 merged commit 5fa7032 into marcinz606:main Aug 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants